package client;

import java.awt.event.*;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.ListIterator;

import server.*;

public class Control implements ActionListener, KeyListener, MouseListener {
	//private static String host = java.net.InetAddress.getLocalHost().getHostAddress();
	//private static String service = "rmi://145.89.125.184/"+Login.refName;
	private MyJApplet app;
	private MyJLoginPanel loginPanel;
	private MyJUpdatePanel updatePanel;
	private Cijferlijst cijferlijst;
	private ArrayList<String[]> cijfers;
	private MyObserver observer;
	
	public Control(MyJApplet myJApplet) {
		app = myJApplet;
		loginPanel = new MyJLoginPanel(this);
		app.add(loginPanel);
	}
	
	public void doStart() {
		
	}
	
	public void doStop() {
		
	}
	
	public void doDestroy() {
		
	}
	
	public void doLogin(String name, String password) {
		try {
			
			String service = "rmi://"+app.getCodeBase().getHost()+"/"+Login.refName;
			System.out.println(app.getCodeBase().getHost());
			Login login = (Login)Naming.lookup(service);
			Cijferlijst rem = (Cijferlijst)login.login(name, password);

			if(rem == null)	{ 
				loginPanel.setLabel("Inloggen mislukt!");
			} else { 
				app.remove(loginPanel);
				updatePanel = new MyJUpdatePanel(this);
				app.add(updatePanel);
				this.cijferlijst = rem;
				try	{
					MyObserver obexport = new MyObserverImpl(this);
					observer = (MyObserver) UnicastRemoteObject.exportObject(obexport,0);
					cijferlijst.addMyObserver(observer);
				} catch (RemoteException re) {
					System.out.println("\nMyApplet - Observer maken gefaald!!!");
					re.printStackTrace();
				}
				getCijferlijst();
				app.repaint();
				app.validate();
			}
		} catch (MalformedURLException e) {
			loginPanel.setLabel(e.getMessage()+" Netwerk fout");
		} catch (RemoteException e) {
			loginPanel.setLabel(e.getMessage()+" Netwerk fout");
		} catch (NotBoundException e) {
			loginPanel.setLabel(e.getMessage()+" Netwerk fout");
		} catch(NullPointerException e)	{
			loginPanel.setLabel(e.getMessage()+" Ongeldige gebruikersnaam/wachtwoord combinatie");
		} catch(ClassCastException e) {
			loginPanel.setLabel(e.getMessage()+" Onbekende fout");
		} 
	}
	
	public void getCijferlijst() { 
		try { 
			updatePanel.getData().clear();
			cijfers = cijferlijst.selectAll();
			for(ListIterator<String[]> i = cijfers.listIterator(); i.hasNext();)
			{
				String[] dataString = (String[])i.next();				
				updatePanel.addRow(dataString[0], dataString[1]);
			}
		}
		catch(RemoteException re)
		{
			System.out.println("Exception bij update\nMyListCard - getCijferlijst()");
		} catch(Exception e) {
			System.out.println("Exception");
		}
		
		updatePanel.repaint();
	}
	
	public void doInsert() {
		HashMap<String, String> hm = updatePanel.getFields();
		if( this.doValidate(hm.get("student"), hm.get("cijfer") ) ) {
			try	{
				cijferlijst.insert(hm.get("student"),  hm.get("cijfer"));
				updatePanel.clearFields();
			} catch(RemoteException re) {
				re.printStackTrace();
			}
		}
	}
	
	public void doUpdate() {
		HashMap<String, String> hm = updatePanel.getFields();
		if( this.doValidate(hm.get("student"), hm.get("cijfer") ) ) {
			int a = updatePanel.getSelectedRow();
			if( a == -1 ) {
				updatePanel.setError("U heeft geen item uit de lijst geselecteerd.");
				return;
			}
			String[] student = (String[])cijfers.get(a);
			try {
				cijferlijst.update(student[0], hm.get("student"),  hm.get("cijfer"));
				updatePanel.clearFields();
			} catch(RemoteException re) {
				
			}
		}
	}
	
	public void doDelete() {
		try {
			int a = updatePanel.getSelectedRow();
			if( a == -1) {
				updatePanel.setError("U heeft geen item uit de lijst geselecteerd.");
				return;
			}
			String[] student = (String[])cijfers.get(a);
			cijferlijst.delete(student[0]);
		} catch(Exception e) {

		}
	}
	
	public boolean doValidate(String student, String cijfer_str) {
		boolean isValid = false;
		if( !student.equals("") && !cijfer_str.equals("") ) {
			try {
				Double cijfer = Double.parseDouble(cijfer_str.replace(",", "."));
				if( cijfer >= 1.0 && cijfer <= 10.0) {
					isValid = true;
				} else {
					throw new NumberFormatException();
				}
			} catch(NumberFormatException e) {
				updatePanel.setError("Ongeldig cijfer ingevoerd.");
			}
		} else {
			updatePanel.setError("Niet alle velden zijn ingevuld!");
		}
		return isValid;
	}
	
	public void doExit() {
		try {
			cijferlijst.deleteMyObserver(observer);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.exit(0);
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand().equals("Exit")) {
			this.doExit();	
		} else if(e.getActionCommand().equals("Login")) {
			doLogin(loginPanel.getUsr(), loginPanel.getPwd());
		} else if(e.getActionCommand().equals("Insert")) {
			System.out.println("Insert");
			this.doInsert();		
		} else if(e.getActionCommand().equals("Update")) {
			System.out.println("Update");
			this.doUpdate();	
		} else if(e.getActionCommand().equals("Delete")) {
			System.out.println("Delete");
			this.doDelete();
		} else if(e.getActionCommand().equals("Clear")) {
			updatePanel.clearFields();
		}
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getKeyCode() == 10) {
			doLogin(loginPanel.getUsr(), loginPanel.getPwd());
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		int a = updatePanel.getSelectedRow();
		updatePanel.setTextField(1, updatePanel.getValueAt(a, 0));
		updatePanel.setTextField(2, updatePanel.getValueAt(a, 1));
		updatePanel.repaint();
		
	}
	
}